package com.example.chinesenation.Controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.chinesenation.Entity.*;
import com.example.chinesenation.Response.ResultType;
import com.example.chinesenation.Response.ServerResponse;
import com.example.chinesenation.Service.*;
import com.example.chinesenation.Utils.Audience;
import com.example.chinesenation.Utils.CommonURL;
import com.example.chinesenation.Utils.DataChanges;
import com.example.chinesenation.Utils.JwtTokenUtil;
import com.example.chinesenation.VO.Collect.CollectArticle;
import com.example.chinesenation.VO.Collect.CollectPolicy;
import com.example.chinesenation.VO.LoginData;
import com.example.chinesenation.VO.Record.VORecord;
import com.example.chinesenation.VO.UserData;
import io.swagger.annotations.ApiOperation;
import org.jsoup.helper.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.sql.Timestamp;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author sakuraFallingDown
 * @version 1.0
 * @date 2021/1/11 15:11
 */
@Controller
@ResponseBody
@RequestMapping("/user")
@CrossOrigin
public class UserController {

    private final Logger logger= LoggerFactory.getLogger(getClass());


    @Autowired
    private UserService userService;
    @Autowired
    private ICollectService collectService;//用户收藏文章
    @Autowired
    private IPolicyCollectService policyCollectService;//用户收藏政策
    @Autowired
    private IAttentionService attentionService;//用户关注内容
    @Autowired
    private INationService nationService;//存56民族
    @Autowired
    private INationCategoryService nationCategoryService;
    @Autowired
    private INationModuleService nationModuleService;
    @Autowired
    private ILogService logService;//登录记录表
    @Autowired
    private IArticleService articleService;
    @Autowired
    private IPolicyListService policyListService;//政策list表

    @Autowired
    private IBrowseRecordPolicyService browseRecordPolicyService;

    @Autowired
    private IBrowseRecordService browseRecordService;

    @Autowired
    private Audience audience;

    /**
     *
     * @param user 用户登录信息，所要用到的就是uid和password
     * @param browse 浏览器信息
     * @param ip 登录ip信息，用于记录登录日志log
     * @return 返回的LoginData，主要返回token和uname
     */
    @ApiOperation("用户登录接口")
    @PostMapping("/login")
    private ServerResponse<LoginData> login(@RequestBody User user,
                                            @RequestParam(value ="browse",required = false) String browse,
                                            @RequestParam(value ="ip",required = false)String ip){

        return userService.login(user.getUid(),user.getPassword(),browse,ip,audience);
    }

    /**
     *
     * @param user 传来的用户注册信息
     * @return 返回是否注册成功
     */
    @ApiOperation("用户注册接口")
    @PostMapping("/register")
    private ServerResponse<String> register(@RequestBody User user){
        return userService.register(user);
    }

    /**
     *
     * @param token 用户token
     * @param user 需要更新的数据
     * @return 返回是否更新成功
     */
    @ApiOperation("用户更新数据接口")
    @PostMapping("/update")
    private ServerResponse<String> update(@RequestHeader(value = "token") String token,
                                          @RequestBody User user){
        if(token!=null&&!token.equals("")){
            String uid=JwtTokenUtil.getUserId(token,audience);
            user.setUid(uid);
            return userService.update(user);
        }else{
            return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        }
    }

    /**
     *
     * @param token 用户token
     * @return 返回该token对应的uid的用户信息
     */
    @ApiOperation("获取用户信息接口")
    @PostMapping("/review")
    private ServerResponse<UserData> review(@RequestHeader("token") String token){
        String uid= JwtTokenUtil.getUserId(token,audience);
        UserData userData=new UserData();
        User user = userService.findUserButNotUidAndPassword(uid, token);
        userData.setUser(user);//去除用户中的uid以及password，保证用户安全
        return ServerResponse.createSuccessResponse("查询成功",userData);
    }


    /**
     *
     * @param token 用户token
     * @param current 分页查询条件
     * @param size  分页查询条件
     * @return 返回该用户关注的民族模块信息
     */
    @ApiOperation("查看用户关注列表接口")
    @PostMapping("/review/attention")//查看关注的模块
    private ServerResponse<IPage<Attention>> attention(@RequestHeader("token") String token,
                                                       @RequestParam(value ="current")int current,
                                                       @RequestParam(value ="size")int size){
        String uid= JwtTokenUtil.getUserId(token,audience);
        IPage<Attention> attentionIPage=attentionService.getByUid(uid,current,size);//用户关注的所有信息id,降序排序
        List<Attention> attentions=attentionIPage.getRecords();
        if(attentions==null||attentions.size()==0) {
            return ServerResponse.createSuccessResponse("暂无关注");
        }
        return ServerResponse.createSuccessResponse("查询关注模块成功",attentionIPage);
    }

    /**
     *
     * @param token 用户token
     * @param id 上一个attention返回的attentionId
     * @return
     */
    @ApiOperation("取消关注某个主键为Id的Attention的接口")
    @PostMapping("/review/dropattention")//取消关注，传来的值为attention的id
    private ServerResponse<String> dropAttention(@RequestHeader("token") String token,
                                                 @RequestParam("id")String id){
        String uid= JwtTokenUtil.getUserId(token,audience);
        if(attentionService.removeById(id)) {
            return ServerResponse.createSuccessResponse("取消关注成功");
        }else{
            return ServerResponse.createErrorsResponse(ResultType.ERROR);
        }
    }

    /**
     *
     * @param token 用户token
     * @param current 分页查询条件
     * @param size  分页查询条件
     * @return 返回该用户收藏民族文章信息
     */
    @ApiOperation("查看用户收藏民族文章信息列表接口")
    @PostMapping("/review/collect")//查看收藏文章
    private ServerResponse<IPage<CollectArticle>> Collect(@RequestHeader("token") String token,
                                                          @RequestParam(value ="current")int current,
                                                          @RequestParam(value ="size")int size){
        if(token==null||token.equals("")) return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        String uid= JwtTokenUtil.getUserId(token,audience);
        IPage<Collect> collectIPage=collectService.getByUid(uid,current,size);//用户关注的所有信息id,降序排序
        List<Collect> collects=collectIPage.getRecords();//用户查询出来的记录;
        if(collects==null||collects.size()==0) {
            return ServerResponse.createSuccessResponse("暂无收藏文章");
        }
        //将分页数据流转换为前端分页显示所需数据流 from Collect to CollectArticle
        IPage<CollectArticle> collectArticleIPage=new Page<>(current,size);
        collectArticleIPage.setTotal(collectIPage.getTotal());
        collectArticleIPage.setPages(collectIPage.getPages());
        List<String> articleIds = collects.stream().map(Collect::getArticleId).collect(Collectors.toList());
        List<Article> articles = articleService.listByIds(articleIds);
        Map<String, Article> articleMap = articles.stream().collect(Collectors.toMap(Article::getId, Function.identity()));
        List<CollectArticle> collectArticles = collects.stream().map(collect -> {
            CollectArticle ca = new CollectArticle();
            ca.setArticleId(collect.getArticleId());
            ca.setCreateTime(collect.getCreateTime());//记录收藏时间
            ca.setId(collect.getId());
            if(!articleMap.containsKey(collect.getArticleId())) return ca;
            Article article = articleMap.get(collect.getArticleId());
            ca.setArticleAuthor(article.getTag());
            ca.setArticleTitle(article.getTitle());
            String url = DataChanges.findTheFirstURL(DataChanges.fromJsonToListString(article.getContent()));
            if (url != null && (url.contains(".jpg") || url.contains(".png"))) {
                ca.setUrl(CommonURL.imgUrl + url);
                ca.setType(DataChanges.getUrlType(url));
            }
            return ca;
        }).collect(Collectors.toList());
        collectArticleIPage.setRecords(collectArticles);
        return ServerResponse.createSuccessResponse("查询收藏文章模块成功",collectArticleIPage);
    }

    /**
     *
     * @param token 用户token
     * @param id 上一个接口传过去的collectId
     * @return
     */
    @ApiOperation("取消收藏主键为Id的民族文章Article接口")
    @PostMapping("/review/droparticlecollect")//按照文章收藏表的主键取消收藏文章
    private ServerResponse<String> dropCollect(@RequestHeader("token") String token,
                                               @RequestParam("id")String id){
        String uid= JwtTokenUtil.getUserId(token,audience);
        if(collectService.removeById(id)) {
            return ServerResponse.createSuccessResponse("取消该文章收藏成功");
        }else{
            return ServerResponse.createErrorsResponse(ResultType.ERROR);
        }
    }

    /**
     *
     * @param token 用户token
     * @param current 分页查询条件
     * @param size  分页查询条件
     * @return 返回该用户收藏政策信息
     */
    @ApiOperation("查看收藏政策列表接口")
    @PostMapping("/review/policycollect")//查看收藏政策
    private ServerResponse<IPage<CollectPolicy>> PolicyCollect(@RequestHeader("token") String token,
                                                               @RequestParam(value ="current")int current,
                                                               @RequestParam(value ="size")int size){
        if(token==null||token.equals("")) return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        String uid= JwtTokenUtil.getUserId(token,audience);
        IPage<PolicyCollect> collectIPage=policyCollectService.getByUid(uid,current,size);//用户关注的所有信息id,降序排序
        List<PolicyCollect> collects=collectIPage.getRecords();
        if(collects==null||collects.size()==0) {
            return ServerResponse.createSuccessResponse("暂无收藏政策");
        }
        //将分页数据流转换为
        IPage<CollectPolicy> collectPolicyIPage=new Page<>(current,size);
        collectPolicyIPage.setTotal(collectIPage.getTotal());
        collectPolicyIPage.setPages(collectIPage.getPages());
        List<String> policyIds = collects.stream().map(PolicyCollect::getPolicyId).collect(Collectors.toList());
        List<Policy> policies = policyListService.listByIds(policyIds);
        Map<String, Policy> policyMap = policies.stream().collect(Collectors.toMap(Policy::getId, Function.identity()));

        List<CollectPolicy> collectPolicies = collects.stream().map(policyCollect -> {
            CollectPolicy cp = new CollectPolicy();
            cp.setPolicyId(policyCollect.getPolicyId());
            cp.setCreateTime(policyCollect.getCreateTime());//记录收藏时间
            cp.setId(policyCollect.getId());
            if(!policyMap.containsKey(policyCollect.getPolicyId())) return cp;
            Policy policy = policyMap.get(policyCollect.getPolicyId());
            cp.setPolicyAuthor(policy.getPublisher());
            cp.setPolicyTitle(policy.getTitle());
            String url = DataChanges.findTheFirstURL(DataChanges.fromJsonToListString(policy.getContent()));
            if (url != null && (url.contains(".jpg") || url.contains(".png"))) {
                cp.setUrl(CommonURL.imgUrl + url);
                cp.setType(DataChanges.getUrlType(url));
            }
            return cp;
        }).collect(Collectors.toList());
        collectPolicyIPage.setRecords(collectPolicies);
        return ServerResponse.createSuccessResponse("查询收藏文章模块成功",collectPolicyIPage);
    }

    /**
     *
     * @param token 用户token
     * @param id 上一个接口返回的收藏记录主键Id
     * @return
     */
    @ApiOperation("取消收藏主键为Id的民族政策Policy接口")
    @PostMapping("/review/droppolicycollect")//按照政策收藏表的主键取消收藏政策
    private ServerResponse<String> dropPolicyCollect(@RequestHeader("token") String token,
                                                     @RequestParam("id")String id){
        String uid= JwtTokenUtil.getUserId(token,audience);
        if(policyCollectService.removeById(id)) {
            return ServerResponse.createSuccessResponse("取消关注成功");
        }else{
            return ServerResponse.createErrorsResponse(ResultType.ERROR);
        }
    }

    /**
     *
     * @param token 用户token
     * @param current 分页查询条件
     * @param size  分页查询条件
     * @return 返回该用户浏览过的文章记录（未去重）
     */
    @ApiOperation("查询浏览民族文章信息记录列表")
    @PostMapping("/review/articlerecord")
    private ServerResponse<IPage<VORecord>> ArticleRecord(@RequestHeader("token") String token,
                                                          @RequestParam(value ="current")int current,
                                                          @RequestParam(value ="size")int size){
        String uid=JwtTokenUtil.getUserId(token,audience);
        QueryWrapper<BrowseRecord> qw=new QueryWrapper<>();
        qw.eq("uid",uid);
        qw.orderByDesc("create_time");//按照浏览时间排序，降序

        IPage<BrowseRecord> page=new Page<>(current,size);

        IPage<VORecord> voRecordIPage=new Page<>(current,size);
        IPage<BrowseRecord> browseRecordIPage=browseRecordService.page(page,qw);
        List<BrowseRecord> records=browseRecordIPage.getRecords();
        if (records == null || records.size() == 0) {//如果查询的结果为空，表示
            return ServerResponse.createSuccessResponse("无浏览记录");
        }
        voRecordIPage.setPages(browseRecordIPage.getPages());
        voRecordIPage.setTotal(browseRecordIPage.getTotal());
        List<String> articleIds = records.stream().map(BrowseRecord::getArticleId).collect(Collectors.toList());
        List<Article> articles = articleService.listByIds(articleIds);

        //生成hashMap用于O(1)查找key的value
        //由于对于特定序列的key不一定再mysql中查找到的序列也为原序列，故建立hashmap
        Map<String, Article> articleMap = articles.stream().collect(Collectors.toMap(Article::getId, Function.identity()));
        List<VORecord> voRecords = records.stream().map(record -> {
            VORecord voRecord = new VORecord();
            if(!articleMap.containsKey(record.getArticleId())) return voRecord;
            Article article = articleMap.get(record.getArticleId());
            DataChanges.fromArticleToVORecord(article, voRecord);
            voRecord.setRecordId(record.getId());
            voRecord.setRecordTime(record.getCreateTime());
            return voRecord;
        }).collect(Collectors.toList());
        if (voRecords.size() != 0) {
            voRecordIPage.setRecords(voRecords);
            return ServerResponse.createSuccessResponse("查找文章浏览记录成功", voRecordIPage);
        } else {
            return ServerResponse.createErrorsResponse(ResultType.ERROR);
        }

    }

    /**
     *
     * @param token 用户token
     * @param current 分页查询条件
     * @param size  分页查询条件
     * @return 返回该用户浏览过的政策记录（未去重）
     */

    @ApiOperation("查询浏览民族政策记录列表")
    @PostMapping("/review/policyrecord")
    private ServerResponse<IPage<VORecord>> PolicyRecord(@RequestHeader("token") String token,
                                                         @RequestParam(value ="current")int current,
                                                         @RequestParam(value ="size")int size){
        String uid=JwtTokenUtil.getUserId(token,audience);
        QueryWrapper<BrowseRecordPolicy> qw=new QueryWrapper<>();
        qw.eq("uid",uid);
        qw.orderByDesc("create_time");//按照浏览时间排序，降序
        IPage<BrowseRecordPolicy> page=new Page<>(current,size);

        IPage<VORecord> voPolicyRecordIPage=new Page<>(current,size);

        IPage<BrowseRecordPolicy> browseRecordPolicyIPage=browseRecordPolicyService.page(page,qw);
        List<BrowseRecordPolicy> recordPolicies=browseRecordPolicyIPage.getRecords();
        if(recordPolicies==null||recordPolicies.size()==0) {
            return ServerResponse.createSuccessResponse("无浏览记录");

        }
        voPolicyRecordIPage.setPages(browseRecordPolicyIPage.getPages());
        voPolicyRecordIPage.setTotal(browseRecordPolicyIPage.getTotal());
        List<String> policyIds = recordPolicies.stream().map(BrowseRecordPolicy::getPolicyId).collect(Collectors.toList());
        List<Policy> policies = policyListService.listByIds(policyIds);
        Map<String, Policy> policyMap = policies.stream().collect(Collectors.toMap(Policy::getId, Function.identity()));

        List<VORecord> voRecords = recordPolicies.stream().map(recordPolicy -> {
            VORecord voRecord = new VORecord();
            if(!policyMap.containsKey(recordPolicy.getPolicyId())) return voRecord;
            Policy policy = policyMap.get(recordPolicy.getPolicyId());
            DataChanges.fromPolicyToVORecord(policy, voRecord);
            voRecord.setRecordId(recordPolicy.getId());
            voRecord.setRecordTime(recordPolicy.getCreateTime());
            return voRecord;
        }).collect(Collectors.toList());
        if (voRecords.size() != 0) {
            voPolicyRecordIPage.setRecords(voRecords);
            return ServerResponse.createSuccessResponse("查找政策浏览记录成功", voPolicyRecordIPage);
        } else {
            return ServerResponse.createErrorsResponse(ResultType.ERROR);
        }

        
    }

    /**
     *
     * @param token 用户token
     * @param recordId 前端传递的民族文章信息记录的id（非文章id）
     * @return
     */
    //删除浏览记录
    @ApiOperation("删除主键为recordId的民族文章信息记录")
    @PostMapping("/review/deletearticlerecord")
    private ServerResponse<String> deleteArticleRecord(@RequestHeader("token") String token,
                                                       @RequestParam("recordId") String recordId){
        if(token !=null&&!token.equals("")){
            if(browseRecordService.removeById(recordId)){
                return ServerResponse.createSuccessResponse("删除成功");
            }else{
                return ServerResponse.createErrorsResponse(ResultType.ERROR);
            }
        }else{
            return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        }
    }

    /**
     *
     * @param token 用户token
     * @param recordId 前端传递的政策记录的id（非政策id）
     * @return
     */

    @ApiOperation("删除主键为recordId的政策信息记录")
    @PostMapping("/review/deletepolicyrecord")
    private ServerResponse<String> deletePolicyRecord(@RequestHeader("token") String token,
                                                      @RequestParam("recordId")String recordId){
        if(token !=null&&!token.equals("")){
            if(browseRecordPolicyService.removeById(recordId)){
                return ServerResponse.createSuccessResponse("删除成功");
            }else{
                return ServerResponse.createErrorsResponse(ResultType.ERROR);
            }
        }else{
            return ServerResponse.createErrorsResponse(ResultType.TOKENNULL);
        }
    }

}
